我setInterval每秒运行一段代码 30 次。这很好用,但是当我选择另一个选项卡时(以便带有我的代码的选项卡变为非活动状态),由于setInterval某种原因,它被设置为空闲状态。
setInterval
我做了这个简化的测试用例(http://jsfiddle.net/7f6DX/3/):
var $div = $('div'); var a = 0; setInterval(function() { a++; $div.css("left", a) }, 1000 / 30);
如果您运行此代码然后切换到另一个选项卡,请等待几秒钟然后返回,动画会在您切换到另一个选项卡时继续播放。
因此,如果选项卡处于非活动状态,动画不会每秒运行 30 次。这可以通过计算setInterval每秒调用函数的次数来确认 - 如果选项卡处于非活动状态,这将不是 30,而是 1 或 2。
我想这是通过设计完成的,以提高系统性能,但是有没有办法禁用这种行为?
在我的情况下,这实际上是一个劣势。
在大多数浏览器上,非活动选项卡的执行优先级较低,这可能会影响 JavaScript 计时器。
如果您的过渡值是使用 帧之间经过的实时 而不是每个间隔的固定增量来计算的,您不仅可以解决此问题,还可以通过使用 requestAnimationFrame 来实现令人窒息的动画,因为如果处理器不是,它可以达到 60fps很忙。
这是一个使用动画属性转换的 vanilla JavaScript 示例requestAnimationFrame:
requestAnimationFrame
var target = document.querySelector('div#target') var startedAt, duration = 3000 var domain = [-100, window.innerWidth] var range = domain[1] - domain[0] function start() { startedAt = Date.now() updateTarget(0) requestAnimationFrame(update) } function update() { let elapsedTime = Date.now() - startedAt // playback is a value between 0 and 1 // being 0 the start of the animation and 1 its end let playback = elapsedTime / duration updateTarget(playback) if (playback > 0 && playback < 1) { // Queue the next frame requestAnimationFrame(update) } else { // Wait for a while and restart the animation setTimeout(start, duration/10) } } function updateTarget(playback) { // Uncomment the line below to reverse the animation // playback = 1 - playback // Update the target properties based on the playback position let position = domain[0] + (playback * range) target.style.left = position + 'px' target.style.top = position + 'px' target.style.transform = 'scale(' + playback * 3 + ')' } start() body { overflow: hidden; } div { position: absolute; white-space: nowrap; } <div id="target">...HERE WE GO</div>
@UpTheCreek 评论:
很好的演示问题,但仍然有一些事情需要继续运行。
如果您有 需要 在给定时间间隔精确执行的后台任务,您可以使用HTML5 Web Workers。请查看下面的 Møhre 答案以获取更多详细信息…
这个问题和许多其他问题可以通过使用 CSS 过渡/动画而不是基于 JavaScript 的动画来避免,这会增加相当大的开销。我推荐这个 jQuery 插件 ,它可以让你从 CSS 转换中受益,就像animate()方法一样。
animate()